/**
 * 
 */
package com.wilmar.process.web.actions;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.task.Task;

import com.wilmar.common.comparator.CommonDescendingComparator;
import com.wilmar.common.util.PageinationEntity;
import com.wilmar.process.core.ProcessSystemDeclareKeys;
import com.wilmar.process.core.services.api.ISystemExecutionService;
import com.wilmar.process.core.services.api.ISystemHistoryProcessInstanceService;
import com.wilmar.process.core.services.api.ISystemHistoryTaskInstanceService;
import com.wilmar.process.core.services.api.ISystemProcessAuthorityService;
import com.wilmar.process.core.services.api.ISystemProcessDefinitionService;
import com.wilmar.process.core.services.api.ISystemProcessInstanceService;
import com.wilmar.process.core.services.api.ISystemTaskInstanceService;
import com.wilmar.process.core.services.spi.IFormLocationService;
import com.wilmar.process.entity.ProcessAuthority;
import com.wilmar.process.entity.ProcessReleaseNotes;
import com.wilmar.process.entity.User;
import com.wilmar.process.entity.query.ProcessDefinitionQueryObject;
import com.wilmar.process.entity.vo.ProcessAuthorityVO;
import com.wilmar.process.entity.vo.ProcessDefinitionVO;
import com.wilmar.process.exception.DirtyDataException;
import com.wilmar.process.exception.NoUserSessionException;
import com.wilmar.process.exception.ObjectNotFoundException;
import com.wilmar.process.exception.ParameterException;
import com.wilmar.process.web.form.ProcessDefinitionDeploymentForm;

/**
 * @author MaKuBEX E-mail:makubexnet@gmail.com
 * @version 1.0.0 at Aug 3, 2009 1:45:14 PM
 * 
 */
public class ProcessDefinitionAction extends ProcessActionSupport {
	protected static final String ACTION_RESULT_LIST = "list";
	protected static final String ACTION_RESULT_DEPLOY_PAGE = "deploy-page";
	protected static final String ACTION_RESULT_IMAGE = "image";
	protected static final String ACTION_RESULT_IMAGE_PAGE = "image-page";
	protected static final String ACTION_RESULT_START_FORM = "start-form";
	protected static final String ACTION_RESULT_GO_AUTHORITY_LIST = "go-authority-list";
	protected static final String ACTION_RESULT_AUTHORITY_LIST = "authority-list";
	protected static final String ACTION_RESULT_AUTHORIZATION = "authorization";
	protected static final String ACTION_RESULT_AUTHORIZATION_VIEW = "authorization-view";
	protected static final String ACTION_RESULT_AUTHORIZATION_UNDO = "authorization-undo-list";

	protected ISystemProcessAuthorityService systemProcessAuthorityService;
	protected ISystemProcessDefinitionService systemProcessDefinitionService;
	protected ISystemProcessInstanceService systemProcessInstanceService;
	protected ISystemHistoryProcessInstanceService systemHistoryProcessInstanceService;
	protected ISystemTaskInstanceService systemTaskInstanceService;
	protected ISystemHistoryTaskInstanceService systemHistoryTaskInstanceService;
	protected ISystemExecutionService systemExecutionService;
	protected IFormLocationService formLocationService;

	private ProcessDefinitionDeploymentForm deploymentForm;
	private String startForm;
	private List<ProcessDefinitionVO> processDefinitionVOList;
	private InputStream imageStream;
	private List<ProcessAuthority> processAuthorityList;
	private ProcessAuthority processAuthority;
	private List<ProcessAuthorityVO> processAuthorityVOList;

	protected ProcessDefinitionQueryObject processDefinitionQueryObject;

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = 7404857370645603513L;

	public String doDeployForward() {
		return ACTION_RESULT_DEPLOY_PAGE;
	}

	public String doDeploy() throws ObjectNotFoundException, NoUserSessionException {
		User user = super.getCurrentUser();
		if (user == null) {
			throw new ObjectNotFoundException("you must login first!");
		}
		ProcessReleaseNotes processReleaseNote = deploymentForm
				.getProcessReleaseNotes();
		processReleaseNote.setCreatePerson(user.getUserno());
		processReleaseNote.setOuterSystem(user.getOuterSystem());
		systemProcessDefinitionService.deployProcessDefinition(deploymentForm
				.getDefinitionPackage(), processReleaseNote);
		return ACTION_RESULT_GO_AUTHORITY_LIST;
	}

	public String doGetDefinitionImageForward() {
		return ACTION_RESULT_IMAGE_PAGE;
	}

	public String doGetDefinitionImage() throws ObjectNotFoundException,
			ParameterException {
		if (super.processInformation.getProcessDefinitionId() != null
				&& super.processInformation.getProcessDefinitionId().trim()
						.length() != 0) {
			this.imageStream = this.systemProcessDefinitionService
					.getDefinitionImageById(super.processInformation
							.getProcessDefinitionId());
		} else if (super.processInformation.getProcessInstanceId() != null
				&& super.processInformation.getProcessInstanceId().trim()
						.length() != 0) {
			try {
				ProcessInstance pi = this.systemProcessInstanceService
						.getDetailById(super.processInformation
								.getProcessInstanceId().trim());
				this.imageStream = this.systemProcessDefinitionService
						.getDefinitionImageById(pi.getProcessDefinitionId());
			} catch (ObjectNotFoundException e) {
				HistoryProcessInstance pi = this.systemHistoryProcessInstanceService
						.getDetailById(super.processInformation
								.getProcessInstanceId().trim());
				this.imageStream = this.systemProcessDefinitionService
						.getDefinitionImageById(pi.getProcessDefinitionId());
			}
		} else if (super.processInformation.getTaskInstanceId() != null
				&& super.processInformation.getTaskInstanceId().trim().length() != 0) {
			try {
				Task ti = this.systemTaskInstanceService
						.getDetailById(super.processInformation
								.getTaskInstanceId().trim());
				this.imageStream = this.systemProcessDefinitionService
						.getDefinitionImageById(this.systemExecutionService
								.getDetailById(ti.getExecutionId())
								.getProcessDefinitionId());
			} catch (ObjectNotFoundException e) {
				HistoryTask ti = this.systemHistoryTaskInstanceService
						.getDetailById(super.processInformation
								.getTaskInstanceId().trim());
				this.imageStream = this.systemProcessDefinitionService
						.getDefinitionImageById(this.systemExecutionService
								.getDetailById(ti.getExecutionId())
								.getProcessDefinitionId());
			}
		} else
			throw new ParameterException("parameter exception!");
		return ACTION_RESULT_IMAGE;
	}

	public String doGetDefinitionList() throws DirtyDataException, NoUserSessionException {
		User user = super.getCurrentUser();
		if (super.pageination == null)
			super.pageination = new PageinationEntity(0,
					ProcessSystemDeclareKeys.SYSTEM_DEFAULT_PAGEINATION_LIMIT);
		if (this.processDefinitionQueryObject != null)
			this.processDefinitionQueryObject.setPageination(super.pageination);
		List<ProcessDefinition> pdList = this.systemProcessDefinitionService
				.getListAllWithLastestVersion(user,
						this.processDefinitionQueryObject);
		this.processDefinitionVOList = this.systemProcessDefinitionService
				.convertToVOList(pdList);
		Collections.sort(this.processDefinitionVOList,
				new CommonDescendingComparator());
		return ACTION_RESULT_LIST;
	}

	public String doGoToStartForm() throws Exception {
		String startFormKey = null;
		if (super.processInformation.getProcessDefinitionId() != null
				&& super.processInformation.getProcessDefinitionId().trim()
						.length() != 0) {
			startFormKey = this.systemProcessDefinitionService
					.getStartFormByProcessDefinitionId(super.processInformation
							.getProcessDefinitionId());
		} else if (super.processInformation.getProcessDefinitionKey() != null) {
			startFormKey = this.systemProcessDefinitionService
					.getStartFormByProcessDefinitionKey(super.processInformation
							.getProcessDefinitionKey());
		}
		this.startForm = this.formLocationService.doLocation(startFormKey);
		return ACTION_RESULT_START_FORM;
	}

	public String doGetAuthorityList() {
		List<ProcessDefinition> pdList = this.systemProcessDefinitionService
				.getListAllWithLastestVersion(super.pageination);
		this.processDefinitionVOList = this.systemProcessDefinitionService
				.convertToVOList(pdList);
		Collections.sort(this.processDefinitionVOList,
				new CommonDescendingComparator());
		return ACTION_RESULT_AUTHORITY_LIST;
	}

	public String doGotoAuthorition() {

		// 机构、角色 等获取设置
		return ACTION_RESULT_AUTHORIZATION;
	}

	public String doAuthorition() throws ObjectNotFoundException, NoUserSessionException {
		if (processAuthorityList != null && processAuthorityList.size() > 0) {
			User user = super.getCurrentUser();
			if (user == null) {
				throw new ObjectNotFoundException("you must login first!");
			}
			List<ProcessAuthority> procAuthFilterList = new ArrayList<ProcessAuthority>();
			for (ProcessAuthority procAuth : this.processAuthorityList) {
				if (procAuth != null) {
					procAuth.setCreatePerson(user.getName());
					procAuth.setCreateTime(new Date());
					procAuth.setOuterSystem(user.getOuterSystem());
					procAuthFilterList.add(procAuth);
				}
			}

			systemProcessAuthorityService.saveAllAuthority(procAuthFilterList);
		}
		return ACTION_RESULT_GO_AUTHORITY_LIST;
	}

	public String doGetViewAuthorityList() throws ObjectNotFoundException, NoUserSessionException {
		User user = super.getCurrentUser();
		if (user == null) {
			throw new ObjectNotFoundException("you must login first!");
		}
		String outerSystem = user.getOuterSystem();
		List<ProcessAuthority> processAuthoritys = systemProcessAuthorityService
				.getListByProcessDefinitionKeyAndOuterSystem(
						this.processAuthority.getProcessDefinitionKey(),
						outerSystem);
		this.processAuthorityVOList = systemProcessAuthorityService
				.convertToVOList(processAuthoritys);

		return ACTION_RESULT_AUTHORIZATION_VIEW;
	}

	public String doGetUndoAuthoritionList() throws ObjectNotFoundException, NoUserSessionException {
		User user = super.getCurrentUser();
		if (user == null) {
			throw new ObjectNotFoundException("you must login first!");
		}
		String outerSystem = user.getOuterSystem();
		List<ProcessAuthority> processAuthoritys = systemProcessAuthorityService
				.getListByProcessDefinitionKeyAndOuterSystem(
						this.processAuthority.getProcessDefinitionKey(),
						outerSystem);
		this.processAuthorityVOList = systemProcessAuthorityService
				.convertToVOList(processAuthoritys);

		return ACTION_RESULT_AUTHORIZATION_UNDO;
	}

	// 事务方法
	public String doUndoAuthorition() throws ObjectNotFoundException, NoUserSessionException {
		User user = super.getCurrentUser();
		if (user == null) {
			throw new ObjectNotFoundException("you must login first!");
		}
		String outerSystem = user.getOuterSystem();
		// 删除根据外部系统和流程key获得的流程权限

		this.systemProcessAuthorityService
				.removeAllAuthorityByProcessDefinitionKeyAndOuterSystem(
						this.processAuthority.getProcessDefinitionKey(),
						outerSystem);

		// 获取前台提供的前台权限，并过滤

		List<ProcessAuthority> procAuthFilterList = new ArrayList<ProcessAuthority>();
		for (ProcessAuthority procAuth : this.processAuthorityList) {
			if (procAuth != null) {
				procAuth.setCreatePerson(user.getName());
				procAuth.setCreateTime(new Date());
				procAuth.setOuterSystem(user.getOuterSystem());
				procAuthFilterList.add(procAuth);
			}
		}

		// 保存
		this.systemProcessAuthorityService.saveAllAuthority(procAuthFilterList);

		return ACTION_RESULT_GO_AUTHORITY_LIST;
	}

	public void doRemoveLastestVersionOfProcessDefinition()
			throws DirtyDataException {
		this.systemProcessDefinitionService.removeProcessDefinitionById(
				this.processInformation.getProcessDefinitionId(),
				this.processInformation.getProcessDeploymentId());
		// 跳转
	}

	public void doRemoveAllVersionOfProcessDefinition() {
		this.systemProcessDefinitionService
				.removeAllVersionOfProcessDefinitionByKey(this.processInformation
						.getProcessDefinitionKey());

		// 跳转
	}

	/**
	 * @return the processDefinitionVOList
	 */
	public List<ProcessDefinitionVO> getProcessDefinitionVOList() {
		return processDefinitionVOList;
	}

	/**
	 * @param processDefinitionVOList
	 *            the processDefinitionVOList to set
	 */
	public void setProcessDefinitionVOList(
			List<ProcessDefinitionVO> processDefinitionVOList) {
		this.processDefinitionVOList = processDefinitionVOList;
	}

	public ProcessDefinitionDeploymentForm getDeploymentForm() {
		return deploymentForm;
	}

	public ISystemProcessDefinitionService getSystemProcessDefinitionService() {
		return systemProcessDefinitionService;
	}

	public void setDeploymentForm(ProcessDefinitionDeploymentForm deploymentForm) {
		this.deploymentForm = deploymentForm;
	}

	public void setSystemProcessDefinitionService(
			ISystemProcessDefinitionService systemProcessDefinitionService) {
		this.systemProcessDefinitionService = systemProcessDefinitionService;
	}

	public ISystemProcessAuthorityService getSystemProcessAuthorityService() {
		return systemProcessAuthorityService;
	}

	public void setSystemProcessAuthorityService(
			ISystemProcessAuthorityService systemProcessAuthorityService) {
		this.systemProcessAuthorityService = systemProcessAuthorityService;
	}

	/**
	 * @return the startForm
	 */
	public String getStartForm() {
		return startForm;
	}

	/**
	 * @param startForm
	 *            the startForm to set
	 */
	public void setStartForm(String startForm) {
		this.startForm = startForm;
	}

	/**
	 * @return the formLocationService
	 */
	public IFormLocationService getFormLocationService() {
		return formLocationService;
	}

	/**
	 * @param formLocationService
	 *            the formLocationService to set
	 */
	public void setFormLocationService(IFormLocationService formLocationService) {
		this.formLocationService = formLocationService;
	}

	/**
	 * @return the imageStream
	 */
	public InputStream getImageStream() {
		return imageStream;
	}

	/**
	 * @param imageStream
	 *            the imageStream to set
	 */
	public void setImageStream(InputStream imageStream) {
		this.imageStream = imageStream;
	}

	public List<ProcessAuthority> getProcessAuthorityList() {
		return processAuthorityList;
	}

	public void setProcessAuthorityList(
			List<ProcessAuthority> processAuthorityList) {
		this.processAuthorityList = processAuthorityList;
	}

	public ProcessAuthority getProcessAuthority() {
		return processAuthority;
	}

	public void setProcessAuthority(ProcessAuthority processAuthority) {
		this.processAuthority = processAuthority;
	}

	public List<ProcessAuthorityVO> getProcessAuthorityVOList() {
		return processAuthorityVOList;
	}

	public void setProcessAuthorityVOList(
			List<ProcessAuthorityVO> processAuthorityVOList) {
		this.processAuthorityVOList = processAuthorityVOList;
	}

	/**
	 * @return the processDefinitionQueryObject
	 */
	public ProcessDefinitionQueryObject getProcessDefinitionQueryObject() {
		return processDefinitionQueryObject;
	}

	/**
	 * @param processDefinitionQueryObject
	 *            the processDefinitionQueryObject to set
	 */
	public void setProcessDefinitionQueryObject(
			ProcessDefinitionQueryObject processDefinitionQueryObject) {
		this.processDefinitionQueryObject = processDefinitionQueryObject;
	}

	/**
	 * @return the systemProcessInstanceService
	 */
	public ISystemProcessInstanceService getSystemProcessInstanceService() {
		return systemProcessInstanceService;
	}

	/**
	 * @param systemProcessInstanceService the systemProcessInstanceService to set
	 */
	public void setSystemProcessInstanceService(
			ISystemProcessInstanceService systemProcessInstanceService) {
		this.systemProcessInstanceService = systemProcessInstanceService;
	}

	/**
	 * @return the systemHistoryProcessInstanceService
	 */
	public ISystemHistoryProcessInstanceService getSystemHistoryProcessInstanceService() {
		return systemHistoryProcessInstanceService;
	}

	/**
	 * @param systemHistoryProcessInstanceService the systemHistoryProcessInstanceService to set
	 */
	public void setSystemHistoryProcessInstanceService(
			ISystemHistoryProcessInstanceService systemHistoryProcessInstanceService) {
		this.systemHistoryProcessInstanceService = systemHistoryProcessInstanceService;
	}

	/**
	 * @return the systemTaskInstanceService
	 */
	public ISystemTaskInstanceService getSystemTaskInstanceService() {
		return systemTaskInstanceService;
	}

	/**
	 * @param systemTaskInstanceService the systemTaskInstanceService to set
	 */
	public void setSystemTaskInstanceService(
			ISystemTaskInstanceService systemTaskInstanceService) {
		this.systemTaskInstanceService = systemTaskInstanceService;
	}

	/**
	 * @return the systemHistoryTaskInstanceService
	 */
	public ISystemHistoryTaskInstanceService getSystemHistoryTaskInstanceService() {
		return systemHistoryTaskInstanceService;
	}

	/**
	 * @param systemHistoryTaskInstanceService the systemHistoryTaskInstanceService to set
	 */
	public void setSystemHistoryTaskInstanceService(
			ISystemHistoryTaskInstanceService systemHistoryTaskInstanceService) {
		this.systemHistoryTaskInstanceService = systemHistoryTaskInstanceService;
	}

	/**
	 * @return the systemExecutionService
	 */
	public ISystemExecutionService getSystemExecutionService() {
		return systemExecutionService;
	}

	/**
	 * @param systemExecutionService the systemExecutionService to set
	 */
	public void setSystemExecutionService(
			ISystemExecutionService systemExecutionService) {
		this.systemExecutionService = systemExecutionService;
	}

}
